package com.scalar.chiptrack.adaptor.osep;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.InventoryLot;
import com.scalar.chiptrack.adaptor.dao.InventoryLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import java.util.Iterator;
import java.util.Date;

import java.io.File;

import jxl.Workbook;
import jxl.Sheet;
import jxl.Cell;
import jxl.CellType;
import jxl.DateCell;

/**
 * Created by IntelliJ IDEA.
 * User: Sudhakar
 * Date: Aug 1, 2007
 * Time: 5:59:01 PM
 */
public class OSEPINVDataParser extends JobHandler implements AdaptorConstants
{
    HashMap m_fgDataMap             = new HashMap();
    HashMap m_fgsheetDataMap        = new HashMap();
    ArrayList CMLsheetList          = new ArrayList();
    private Logger m_parserLogger   = null;
    private String m_dataOutputDir  = null;

    public OSEPINVDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir(VENDOR_NAME_OSEP, INVENTORY_TYPE_FINISHED_GOODS);
            AdaptorUtils.makeAllAdaptorDirs(m_dataOutputDir);
            m_parserLogger = AdaptorUtils.getDataParserLogger(m_dataOutputDir,VENDOR_NAME_OSEP);
            InventoryLotDAO.setLogger(m_parserLogger);
            OsepDAO.setLogger(m_parserLogger);
            AdaptorUtils.setLogger(m_parserLogger);
        }
        catch (ScalarException se)
        {
            log("ERROR!! ERROR!! ERROR!! Exception while loading OSEP FG Inventory output directory details from database, Exception: " + se);
            throw se;
        }
    }
    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main(String args[]) throws Exception
    {
        new OSEPINVDataParser().execute();
    }
    /**
     *
     * @throws Exception
     */
    public void execute() throws Exception
    {
        AdaptorUtils.printHeader(VENDOR_NAME_OSEP+ " FG", CONSTANT_PARSER);

        File doneDestDir = new File(m_dataOutputDir + "/done");

        File wipDataoutDir = new File(m_dataOutputDir);

        File[] fileList = wipDataoutDir.listFiles();

        if ((fileList == null) || (fileList.length <= 3))
        {
            log("No file found in directory: " + wipDataoutDir);
            throw new ScalarException("No file found in directory: " + wipDataoutDir + "----\n\n");
        }

        ArrayList successFileList = new ArrayList();
        boolean success = true;

        //PARSING STARTS FROM HERE
        for (int i = 0; i < fileList.length; i++)
        {
            if (fileList[i].isDirectory() == true)
            {
                continue;
            }

            if (fileList[i].getName() != null && fileList[i].getName().trim().startsWith(OSEPINVFTPAdaptor.FILE_NAME_FGS))
            {
                parseCMLFGWipDailyWip(fileList[i].getAbsolutePath());

                //Add files to success list to move to /done directory
                successFileList.add(fileList[i]);
            }
        }

        try
        {
            if (CMLsheetList == null)
            {
                CMLsheetList = new ArrayList();
            }
            if (CMLsheetList != null && CMLsheetList.size() > 0 )
            {
                log("Updating FG CML Lot Information of Sheet");
                OsepDAO.saveCMLFGLotDetails(null, CMLsheetList);
            }
            CMLsheetList.clear();
            CMLsheetList = null;

        }
        catch (Exception e)
        {
            success = false;
            log("ERROR!! ERROR!! ERROR!! Could not update Ship information into database: " + e);
            e.printStackTrace();
            throw e;
        }
        // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications(VENDOR_NAME_OSEP, true, true, true);

        // To Close All Drop Out Lots
        AdaptorDAO.closeDropOutLots(VENDOR_NAME_OSEP);

        int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( OSEPINVFTPAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

        // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, OSEPINVFTPAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, OSEPINVFTPAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }
        // Step 7
        // Move the successful files to 'done' directory
        if (success)
        {
            AdaptorUtils.moveFilesToDone( successFileList, doneDestDir);
        }
    }//end of execute method

    /**
     *
     * @param fileName
     * @throws Exception
     */
    private void parseCMLFGWipDailyWip(String fileName) throws Exception
    {
        Sheet sheet = null;

        if (fileName == null)
        {
            throw new ScalarException("Filename argument is null");
        }
        try
        {
            File wipStatusFile = new File(fileName);
            if (wipStatusFile.exists() == false)
            {
                throw new ScalarException(fileName + " doesnt exist");
            }

            log("\nFound " + fileName);
            log("Parsing the file for OSEP FG Inventory Report...");
            System.out.println("\nFound " + fileName);
            System.out.println("Parsing the file for OSEP FG Inventory Report...");

            Workbook workbook = Workbook.getWorkbook(wipStatusFile);
            sheet = workbook.getSheet(0);
            CMLsheetList = parseFgSheet(sheet);
            segregateFgInfo( CMLsheetList );
        }
        catch (Exception e)
        {
            throw new ScalarException("Exception " + e);
        }
    }
    /**
     *
     * @param sheet
     * @return
     * @throws Exception
     */
    private ArrayList parseFgSheet(Sheet sheet) throws Exception
    {
        OSEPFGWipStatus osepfgWipStatus = null;
        ArrayList fgWipList = new ArrayList();

        try
        {
            Cell[] row = null;

            for (int rowCount = 1; rowCount < sheet.getRows(); rowCount++)
            {
                row = sheet.getRow(rowCount);

                osepfgWipStatus = new OSEPFGWipStatus();

                if (row.length > 0)
                {
                    if (row[0].getType().equals(CellType.EMPTY))
                    {
                        osepfgWipStatus.setAssyLoc(null);
                    }
                    else
                    {
                        osepfgWipStatus.setAssyLoc(row[0].getContents().trim());
                    }
                }
                if (row.length > 1)
                {
                    if (row[1].getType().equals(CellType.EMPTY))
                    {
                        osepfgWipStatus.setDevice(null);
                    }
                    else
                    {
                        osepfgWipStatus.setDevice(row[1].getContents().trim());
                    }
                }
                if (row.length > 2)
                {
                    if (row[2].getType().equals(CellType.EMPTY))
                    {
                        osepfgWipStatus.setLot(null);
                    }
                    else
                    {
                        osepfgWipStatus.setLot(row[2].getContents().trim());
                    }
                }
                if (row.length > 3)
                {
                    if (row[3].getType().equals(CellType.EMPTY))
                    {
                        osepfgWipStatus.setSplit(null);
                    }
                    else
                    {
                        osepfgWipStatus.setSplit(row[3].getContents().trim());
                    }
                }
                if (row.length > 4)
                {
                    if (row[4].getType().equals(CellType.EMPTY))
                    {
                        osepfgWipStatus.setActualQtyPulled(null);
                    }
                    else
                    {
                        osepfgWipStatus.setActualQtyPulled(row[4].getContents().trim().replaceAll(",", ""));
                    }
                }
                if (row.length > 5)
                {
                    if (row[5].getType().equals(CellType.EMPTY))
                    {
                        osepfgWipStatus.setRec_date(null);
                    }
                    else if (row[5].getType().equals(CellType.DATE))
                    {
                        DateCell dc = (DateCell) row[5];
                        java.util.Date outDate = null;
                        outDate = dc.getDate();
                        if ("America/Los_Angeles".equals(System.getProperty("user.timezone")))
                        {
                            Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.US);
                            cal.setTime(outDate);
                            outDate = new GregorianCalendar(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE)).getTime();
                            osepfgWipStatus.setRec_date(StringUtils.formatDateToString(outDate));
                        }
                        else
                        {
                            Calendar cal = new GregorianCalendar();
                            cal.setTime(outDate);
                            outDate = new GregorianCalendar(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE)).getTime();
                            osepfgWipStatus.setRec_date(StringUtils.formatDateToString(outDate));
                        }
                    }
                }

                //when all the combinations are same making all the rows as One Row...........By adding the Qty
                if (osepfgWipStatus.getLot() != null && osepfgWipStatus.getLot().trim().length() > 0 && !"lot".equalsIgnoreCase(osepfgWipStatus.getLot().trim()))
                {
                    if (m_fgsheetDataMap.containsKey(osepfgWipStatus.getAssyLoc() + osepfgWipStatus.getDevice() + osepfgWipStatus.getLotNumber() + osepfgWipStatus.getActualQtyPulled() + osepfgWipStatus.getRec_date()))
                    {
                        OSEPFGWipStatus osepsheetObj = (OSEPFGWipStatus) m_fgsheetDataMap.get(osepfgWipStatus.getAssyLoc() + osepfgWipStatus.getDevice() + osepfgWipStatus.getLotNumber() + osepfgWipStatus.getActualQtyPulled() + osepfgWipStatus.getRec_date());
                        try
                        {
                            int firstQty = Integer.parseInt(osepsheetObj.getActualQtyPulled());
                            int secondQty = Integer.parseInt(osepfgWipStatus.getActualQtyPulled());
                            int total = firstQty + secondQty;
                            osepsheetObj.setActualQtyPulled(total + "");
                        }
                        catch (NumberFormatException nfe)
                        {
                            nfe.printStackTrace();
                        }
                    }
                    else
                    {
                        m_fgsheetDataMap.put(osepfgWipStatus.getAssyLoc() + osepfgWipStatus.getDevice() + osepfgWipStatus.getLotNumber() + osepfgWipStatus.getActualQtyPulled() + osepfgWipStatus.getRec_date(), osepfgWipStatus);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            throw ex;
        }
        fgWipList.addAll(m_fgsheetDataMap.values());
        return fgWipList;
    }

    /**
     * @param wipInfoList
     */
    private void segregateFgInfo(ArrayList wipInfoList) throws Exception
    {
        InventoryLot inventoryLot = null;
        OSEPFGWipStatus wipStatus = null;

        try
        {
            Iterator iterator = wipInfoList.iterator();

            while (iterator.hasNext())
            {
                wipStatus = (OSEPFGWipStatus) iterator.next();
                String partNumber = wipStatus.getDevice();
                String lotNumber = wipStatus.getLotNumber();

                if (lotNumber != null && partNumber != null)
                {
                    inventoryLot = (InventoryLot) m_fgDataMap.get(lotNumber + partNumber);

                    if (inventoryLot == null)
                    {
                        inventoryLot = new InventoryLot(VENDOR_NAME_OSEP, LOCATION_TYPE_FG);
                        m_fgDataMap.put(lotNumber + partNumber, inventoryLot);
                    }

                    int quantity = 0;
                    if (inventoryLot.getQtyIn() != null)
                    {
                        try
                        {
                            quantity = Integer.parseInt(inventoryLot.getQtyIn());
                        }
                        catch (NumberFormatException npe) {
                        }
                        try
                        {
                            quantity += Integer.parseInt(wipStatus.getActualQtyPulled());
                        }
                        catch (NumberFormatException npe) {
                        }
                    }
                    else
                    {
                        try
                        {
                            quantity = Integer.parseInt(wipStatus.getActualQtyPulled());
                        }
                        catch (NumberFormatException npe) {
                        }
                    }

                    String dateIn = null;
                    String receiveDate = null;
                    //Max Date is Considering as DATE IN
                    if (inventoryLot.getDateIn() != null)
                    {
                        dateIn = inventoryLot.getDateIn();
                    }
                    if (wipStatus.getRec_date() != null && wipStatus.getRec_date().trim().length() > 0)
                    {
                        receiveDate = wipStatus.getRec_date();
                    }
                    if ((receiveDate != null) && (dateIn != null))
                    {
                        java.util.Date tempDate1 = StringUtils.getSQLDate(receiveDate, "MM/dd/yyyy");
                        java.util.Date tempDate2 = StringUtils.getSQLDate(dateIn, "MM/dd/yyyy");
                        if (tempDate1 != null && tempDate2 != null)
                        {
                            if (tempDate1.compareTo(tempDate2) < 0)
                            {
                                receiveDate = dateIn;
                            }
                        }
                    }

                    if (receiveDate == null)
                    {
                        receiveDate = new Date().toString();
                    }

                    String assemblyVendor = null;
                    if ("G".equalsIgnoreCase(wipStatus.getAssyLoc()))
                    {
                        assemblyVendor = VENDOR_NAME_CML;
                    }
                    else if ("L".equalsIgnoreCase(wipStatus.getAssyLoc()))
                    {
                        assemblyVendor = VENDOR_NAME_ATK;
                    }
                    else if ("M".equalsIgnoreCase(wipStatus.getAssyLoc()))
                    {
                        assemblyVendor = VENDOR_NAME_ATP;
                    }
                    else if ("Q".equalsIgnoreCase(wipStatus.getAssyLoc()) || "R".equalsIgnoreCase(wipStatus.getAssyLoc()) || "RA".equalsIgnoreCase(wipStatus.getAssyLoc()) || "SP".equalsIgnoreCase(wipStatus.getAssyLoc()))
                    {
                        assemblyVendor = VENDOR_NAME_CML;
                    }
                    else if ("T".equalsIgnoreCase(wipStatus.getAssyLoc()))
                    {
                        assemblyVendor = VENDOR_NAME_OSET;
                    }

                    inventoryLot.setLotNumber(lotNumber);
                    inventoryLot.setPartNumber(partNumber);
                    inventoryLot.setQtyIn(quantity + "");
                    inventoryLot.setDateIn(receiveDate);
                    inventoryLot.setStatus(LOT_STATUS_RUNNING);
                    inventoryLot.setAssemblyVendor(assemblyVendor);
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            log("!!!ERROR!ERROR! While segregating the OSEP FG Inventory Details" + e);
            System.out.println("!!!ERROR!ERROR! While parsing the OSEP FG Inventory Details" + e);
        }
    }

    /**
     *
     * @param message
     */
    private void log(String message)
    {
        if (message == null) return;

        if (m_parserLogger != null)
        {
            synchronized (m_parserLogger)
            {
                m_parserLogger.logDebug(message + LINE_SEPARATOR);
            }
        }
        else
        {
            System.out.println(message);
        }
    }
}

